package com.zhu.fastFoodRestaurantOrderSystem.service.impl;

import com.zhu.fastFoodRestaurantOrderSystem.exception.BusinessException;
import com.zhu.fastFoodRestaurantOrderSystem.exception.ErrorCode;
import com.zhu.fastFoodRestaurantOrderSystem.model.Item;
import com.zhu.fastFoodRestaurantOrderSystem.model.Order;
import com.zhu.fastFoodRestaurantOrderSystem.model.enumType.ItemType;
import com.zhu.fastFoodRestaurantOrderSystem.model.enumType.OrderStatus;
import com.zhu.fastFoodRestaurantOrderSystem.repository.impl.OrderRepositoryImpl;
import com.zhu.fastFoodRestaurantOrderSystem.repository.OrderRepository;
import com.zhu.fastFoodRestaurantOrderSystem.service.OrderService;
import com.zhu.fastFoodRestaurantOrderSystem.util.ModifiedType;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

public class OrderServiceImpl implements OrderService {

    private static final int MAX_ITEMS = 5;
    private static final LocalTime ICE_COFFEE_END_TIME = LocalTime.of(15, 0);
    private static final String ICE_COFFEE = "冰咖啡";
    private static final String ORANGE_JUICE = "橙汁";
    private static final String COLA = "可乐";

    private static final LocalDateTime time = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));

    private static final OrderRepository orderRepository = new OrderRepositoryImpl();


    @Override
    public void isContainMain(List<Item> items) throws BusinessException{
        if (items == null){
            return;
        }
        if (items.stream().noneMatch(item -> item.getType() == ItemType.MAIN)){
            throw new BusinessException(ErrorCode.ORDER_NO_MAIN_ITEM);
        }
        System.out.println("ok");
    }

    @Override
    public void isDessertOnly(List<Item> items) {
        if (items == null){
            return;
        }
        if (items.stream().allMatch(item -> item.getType() == ItemType.DESSERT)){
            throw new BusinessException(ErrorCode.ORDER_DESSERT_WITHOUT_MAIN);
        }
        System.out.println("ok");
    }


    @Override
    public void checkItemCount(List<Item> items) throws BusinessException{
        if (items.size() <= 0){
            throw new BusinessException(ErrorCode.ORDER_ITEM_INVALID);
        }
        if (items.size() > MAX_ITEMS){
            throw new BusinessException(ErrorCode.ORDER_ITEM_LIMIT_EXCEEDED);
        }
        System.out.println("ok");
    }

    @Override
    public Order createOrder(List<Item> items, boolean isVip) {
        Integer initial = items.size();
        Integer after = 0;

        if (items.size() <= 0){
            throw new BusinessException(ErrorCode.ORDER_ITEM_INVALID);
        }
        String remark = "";
        items = items.stream()
                .filter(item -> !(
                        "冰咖啡".equals(item.getName())
                                && time.toLocalTime().isAfter(ICE_COFFEE_END_TIME)
                ))
                .collect(Collectors.toList());
        after = items.size();
        if (initial > after){
            remark = "（冰咖啡已下架）原订单中有" + initial + "个商品，实际支付" + after + "个商品";
        }
        double price = calculatePrice(items);
        if (isVip){
            price = price * 0.9;
        }
        Order order = new Order(UUID.randomUUID().toString(),items, OrderStatus.CREATED, price, time,remark);
        System.out.println("订单创建成功：" + order);
        orderRepository.save(order);
        return order;
    }

    @Override
    public Order modifyOrder(String orderId, List<Item> items, boolean isVip) {
        Order order = orderRepository.findById(orderId);
        if (order.getStatus() == OrderStatus.PAID){
            throw new BusinessException(ErrorCode.ORDER_PAID);
        }
        if (order.getStatus() == OrderStatus.CANCELLED){
            throw new BusinessException(ErrorCode.ORDER_CANCELLED);
        }
        Integer initial = items.size();
        Integer after = 0;

        if (items.size() <= 0){
            throw new BusinessException(ErrorCode.ORDER_ITEM_INVALID);
        }
        String remark = "";
        items = items.stream()
                .filter(item -> !(
                        "冰咖啡".equals(item.getName())
                                && time.toLocalTime().isAfter(ICE_COFFEE_END_TIME)
                ))
                .collect(Collectors.toList());
        after = items.size();
        if (initial > after){
            remark += "（冰咖啡已下架）原订单中有" + initial + "个商品，实际支付" + after + "个商品";
        }


        double price = calculatePrice(items);
        if (isVip){
            price = price * 0.9;
        }
        remark += "原总结：" + order.getTotalPrice() + "-> 新总价" + price ;
        ModifiedType modifiedType = new ModifiedType();
        String changeRecord = null;

        OrderStatus orderStatus = modifiedType.ModifiedType(order.getItems(), items);
        if (orderStatus.equals(OrderStatus.SINGLE_SUBSTITUTION)){
            changeRecord = "整单替换";
        }

        if (orderStatus.equals(OrderStatus.PARTIAL_MODIFICATION_DELETE_ITEMS)){
            changeRecord = "删除商品";
        }

        if (orderStatus.equals(OrderStatus.PARTIAL_MODIFICATION_ADD_ITEMS)){
            changeRecord = "添加商品";
        }

        if (orderStatus.equals(OrderStatus.PARTIAL_MODIFICATION_REPLACE_ITEMS)){
            changeRecord = "替换商品";
        }
        order = new Order(orderId, items, orderStatus, price, time, remark,changeRecord);
        orderRepository.update(order);
        System.out.println("订单修改成功：" + order);

        return order;
    }

    @Override
    public Order approveOrder(String orderId, boolean operate) {
        Order order = orderRepository.findById(orderId);
        if (!order.getStatus().equals(OrderStatus.SINGLE_SUBSTITUTION) || !order.getStatus().equals(OrderStatus.PARTIAL_MODIFICATION_ADD_ITEMS) || !order.getStatus().equals(OrderStatus.PARTIAL_MODIFICATION_REPLACE_ITEMS) || !order.getStatus().equals(OrderStatus.PARTIAL_MODIFICATION_DELETE_ITEMS)){
            throw new BusinessException(ErrorCode.ORDER_STATUS_ANOMALY);
        }
        if (operate){
            order.setStatus(OrderStatus.CREATED);
            orderRepository.update(order);
        }else {
            order.setStatus(OrderStatus.APPROVAL_FAILED);
            orderRepository.update(order);
        }
        return order;
    }

    @Override
    public void cancelOrder(String orderId) {
        Order order = orderRepository.findById(orderId);
        if (order.getStatus() == OrderStatus.PAID){
            throw new BusinessException(ErrorCode.ORDER_PAID);
        }
        if (order.getStatus() == OrderStatus.CANCELLED){
            throw new BusinessException(ErrorCode.ORDER_CANCELLED);
        }
        if (order.getCreateTime().isBefore(time.minusMinutes(30))){
            order.setStatus(OrderStatus.CANCELLED);
            orderRepository.update(order);
            throw new BusinessException(ErrorCode.ORDER_CANCEL_TIMEOUT);
        }
        order.setStatus(OrderStatus.CANCELLED);
        orderRepository.update(order);
    }

    /*
     * 计算订单价格
     * @param items 商品列表
     * @return  订单价格
     */
    private double calculatePrice(List<Item> items) {
        double price = 0;
        for (Item item : items) {
            price += item.getPrice();
        }
        price = price - hamburgerAndFriesCount(items) * 5 - drinkHalfPrice(items);
        //周末优惠
        if (price >= 100 && time.getDayOfWeek().getValue() == 7){
            price = price - 10;
        }
        return price;
    }




    /**
     * 如果存在订单存在汉堡和薯条
     * @param items 商品列表
     * @return  优惠金额
     */
    private Integer hamburgerAndFriesCount(List<Item> items) {
        Integer hamburgerCount = 0;
        Integer friesCount = 0;
        for (Item item : items) {
            if ("汉堡".equals(item.getName())) {
                hamburgerCount++;
            }
            if ("薯条".equals(item.getName())) {
                friesCount++;
            }
        }
        if (hamburgerCount > 0 && friesCount > 0){
            if (hamburgerCount == friesCount){
                return hamburgerCount;
            }
            if (hamburgerCount > friesCount){
                return friesCount;
            }
            if (friesCount > hamburgerCount){
                return hamburgerCount;
            }
        }
        return 0;
    }



    /**
     * 相同饮料第二杯半价
     * @param items 商品列表
     * @return  优惠金额
     */
    private double drinkHalfPrice(List<Item> items) {
        Integer icedCoffee = 0,
                cola = 0,
                orangeJuice = 0;
        double icedCoffeePrice = 0,
                colaPrice = 0,
                orangeJuicePrice = 0;
        double price = 0;
        for (Item item : items){
            if (ICE_COFFEE.equals(item.getName())){
                icedCoffeePrice = item.getPrice();
                icedCoffee++;
            }
            if (COLA.equals(item.getName())){
                colaPrice = item.getPrice();
                cola++;
            }
            if (ORANGE_JUICE.equals(item.getName())){
                orangeJuicePrice = item.getPrice();
                orangeJuice++;
            }
        }
        if (icedCoffee >= 2){
            price += icedCoffeePrice / 2;
        }
        if (cola >= 2){
            price += colaPrice / 2;
        }
        if (orangeJuice >= 2){
            price += orangeJuicePrice / 2;
        }
        return price;
    }

}
